package com.tiem_files.dao.base;

import com.tiem_files.annot.MyField;
import com.tiem_files.annot.Table;
import com.tiem_files.utils.JDBCUtil;
import org.apache.commons.dbutils.*;
import org.apache.commons.dbutils.handlers.BeanHandler;
import org.apache.commons.dbutils.handlers.BeanListHandler;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;

public class BaseDao <T>{

    private final Class<T> aClass;
     private final String tableName ;
     private final String keyName ;

    public BaseDao(Class<T> aClass){
        this.aClass  = aClass;
        Table annotation = aClass.getDeclaredAnnotation(Table.class);
        if (annotation != null) {
            tableName = annotation.value();
            keyName = annotation.key();
        }else {
            tableName = "tb";
            keyName ="id";
        }
    }

    public List<T> findByCol(String key, String value){

        String sql="select * from "+tableName+" where "+ key +" = ? ";
        QueryRunner qr = new QueryRunner(JDBCUtil.getDataSource());
        List<T>  userList =new ArrayList<>();
        try {
            userList = qr.query(sql, new BeanListHandler<>(aClass),value);
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return userList;
    }

    public List<T> findByCols(String condition, Map<String,Object> map){
        StringBuilder sb=new StringBuilder();
        sb.append("select * from "+tableName+" where  ");
        if (map.isEmpty()){
            sb.delete(sb.lastIndexOf(" where"),sb.length());
        }else {
            //遍历map集合
            Set<String > keySet =map.keySet();
            for (String key:keySet) {
                sb.append(key).append("='").append(map.get(key)).append("' ").append(condition).append(" ");
            }
            sb.delete(sb.lastIndexOf(condition),sb.length());
        }
        QueryRunner qr = new QueryRunner(JDBCUtil.getDataSource());
        List<T>  userList =new ArrayList<>();
        try {
            userList = qr.query(sb.toString(), new BeanListHandler<>(aClass));
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return userList;
    }

    public int save(Object obj){
        int row =0;
        StringBuilder sb =new StringBuilder();
        sb.append("insert into").append(tableName).append("values(");

        Class<?> aClass = obj.getClass();
        Field[] fields = aClass.getDeclaredFields();
        for (int i = 0; i <fields.length ; i++) {
            if (i == fields.length - 1){
                //遍历到最后一个
                sb.append("?)");
            }else {
                sb.append("?,");
            }
        }
        QueryRunner qr = new QueryRunner(JDBCUtil.getDataSource());
        try {
            Object[] paeams = new Object[fields.length];
            for (int i = 0; i <fields.length ; i++) {
                String fieldName = fields[i].getName();
                String methodName = "get"+fieldName.substring(0,1).toUpperCase() + fieldName.substring(1);
                Method method = aClass.getDeclaredMethod(methodName);
                Object value  = method.invoke(obj);
                paeams[i] = value;
            }
            row = qr.update(sb.toString(),paeams);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return row;
    }

    public int update(Object obj) {
        int row = 0;
        StringBuilder sb =new StringBuilder();
        sb.append("update "+ tableName +" set ");

        Class<?> aClass = obj.getClass();
        Field[] fields = aClass.getDeclaredFields();
        for (Field field:fields) {
            String colName = field.getName();
            MyField myField = field.getAnnotation(MyField.class);
            if (null != myField){
                colName =myField.value();
            }
            sb.append(colName).append("=?,");
        }
        sb.delete(sb.lastIndexOf(","),sb.length());
        sb.append("where "+keyName+" = ?");


        QueryRunner qr = new QueryRunner(JDBCUtil.getDataSource());
        try {
        Object[] paeams = new Object[fields.length + 1];
        Object id = null;
        for (int i = 0; i <fields.length ; i++) {
            Field field = fields[i];
            String fieldName = field.getName();
            String colName = field.getName();
            MyField myField = field.getAnnotation(MyField.class);
            if (null != myField){
                colName =myField.value();
            }

            String methodName = "get"+fieldName.substring(0,1).toUpperCase() + fieldName.substring(1);
            Method method = aClass.getDeclaredMethod(methodName);
            Object value  = method.invoke(obj);
            if (colName.equals(keyName)){
                id = value;
            }
            paeams[i] = value;
        }
        paeams[fields.length] = id;
        row = qr.update(sb.toString(),paeams);
    } catch (Exception e) {
        e.printStackTrace();
    }
        return row;
    }

    public T findById(Object id){
        String sql = "select * from" + tableName + "where" + keyName + " = ?";
        QueryRunner qr = new QueryRunner(JDBCUtil.getDataSource());
        //下划线转驼峰
        BeanProcessor bp =new GenerousBeanProcessor();
        RowProcessor rp =new BasicRowProcessor(bp);
        T obj = null;
        try {
            obj =qr.query(sql,new BeanHandler<>(aClass,rp),id);
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return obj;
    }

    public int deleteById(Object id) {
        int row = 0;
        String sql ="delete from" + tableName + " where" + keyName + " = ?";
        QueryRunner qr = new QueryRunner(JDBCUtil.getDataSource());
        try {
            row = qr.update(sql,id);
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return row;
    }
}
